from django.utils.safestring import mark_safe


class Pagination(object):
    """自定义分页组件"""
    def __init__(self, request, temp_name_param, queryset, page_form_method="get",
                 page_size=10, nex=5, prev=5, form_switch=False, first_switch=False,
                 last_switch=False, a_next=False, a_prev=False, sum_page=True):
        """
        :param request: 视图函数的request参数
        :param temp_name_param: 前端form页码跳转的name属性值（默认page）
        :param queryset: 通过ORM从数据库中取到的数据
        :param page_form_method: form页码跳转的method属性值（默认get）
        :param page_size: 每页显示的最大页数（默认10）
        :param nex: 显示当前页前多少页（默认5）
        :param prev: 显示当前页后多少页（默认5）
        :param form_switch: 是否显示 form跳转页码 组件（默认False）
        :param first_switch: 是否显示 首页跳转 组件（默认False）
        :param last_switch: 是否显示 尾页跳转 组件（默认False）
        :param a_next: 是否显示 上一页跳转 组件（默认False）
        :param a_prev: 是否显示 下一页跳转 组件（默认False）
        :param sum_page: 是否显示 总页数 组件（默认True）
        """
        # form跳转页码的name值
        self.temp_name_param = temp_name_param
        # 获取当前页
        if page_form_method == "post":
            # 通过POST获取当前页，默认为1
            now_page = request.POST.get(temp_name_param, 1)
        else:
            # 通过GET获取当前页，默认为1
            now_page = request.GET.get(temp_name_param, 1)

        # 是否是数字
        if now_page == 1:
            pass
        elif now_page.isdecimal():
            now_page = int(now_page)
        else:
            # 不是数据就默认为1
            now_page = 1

        # 当前页
        self.now_page = now_page
        # 每页显示数
        self.page_size = page_size
        # 数据总量
        self.total = queryset.count()
        # 切片开始位
        self.start = (now_page - 1) * page_size
        # 切片结束位
        self.end = now_page * page_size
        # 对ORM从数据库中拿到的数据进行切片，获得当前页面所对应的数据
        self.page_queryset = queryset[self.start:self.end]
        # 总页数
        self.page_num = int(self.total / self.page_size)
        if self.total % self.page_size:
            self.page_num += 1

        # 显示当前页的前多少页
        self.nex = nex
        # 显示当前页的后多少页
        self.prev = prev

        # 让跳转链接里有数据
        from copy import deepcopy
        if page_form_method == "get":
            query_dict = deepcopy(request.GET)
        else:
            query_dict = deepcopy(request.POST)
        query_dict._mutable = True
        self.query_dict = query_dict

        # 组件调用
        self.form_switch = form_switch  # 是否显示 form跳转页码 组件
        self.first_switch = first_switch  # 是否显示 首页跳转 组件
        self.last_switch = last_switch  # 是否显示 尾页跳转 组件
        self.a_next = a_next  # 是否显示 上一页跳转 组件
        self.a_prev = a_prev  # 是否显示 下一页跳转 组件
        self.sum_page = sum_page  # 是否显示 总页数 组件

    def page_form(self):
        """ 添加form部分的html代码
        :return: (str）form部分的html代码
        """
        return f'''<li>
    <form method="get" style="float: left;">
        <label for="page"></label>
        <input id="page" name="{self.temp_name_param}"
               style="border-radius: 0; float: left; display: inline-block; margin-left: -1px; width: 80px"
               type="text" class="form-control" placeholder="页码">
        <button type="submit" style="-moz-border-radius-topleft: 0; -moz-border-radius-bottomleft: 0;
               margin-left: -5px" class="btn btn-default">跳转</button>
    </form>
</li>'''

    def page_first(self):
        """ 添加首页页码的html代码
        :return: （str）html代码
        """
        self.query_dict.setlist(self.temp_name_param, [1])
        return f'<li><a href="?{self.query_dict.urlencode()}">首页</a></li>'

    def page_last(self):
        """ 添加尾页页码的html代码
        :return: （str）html代码
        """
        self.query_dict.setlist(self.temp_name_param, [self.page_num])
        return f'<li><a href="?{self.query_dict.urlencode()}">尾页</a></li>'

    def page_next(self):
        """ 添加下一页的html代码
        :return: （str）html代码
        """
        if self.now_page == self.page_num:
            html = '<li class="disabled"><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li>'
        else:
            self.query_dict.setlist(self.temp_name_param, [self.now_page + 1])
            html = f'<li><a href="?{self.query_dict.urlencode()}" aria-label="Next"><span aria-hidden="true">»</span></a></li>'
        return html

    def page_prev(self):
        if self.now_page == 1:
            html = '<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'
        else:
            self.query_dict.setlist(self.temp_name_param, [self.now_page - 1])
            html = f'<li><a href="?{self.query_dict.urlencode()}" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'
        return html

    def basic(self):
        """ 生成基础的html代码
        :return: （str）html代码
        """
        nex_html = ""
        if self.now_page <= self.nex:
            nex_list = range(1, self.now_page)
        else:
            nex_list = range(self.now_page - self.nex, self.now_page)
        for page in nex_list:
            self.query_dict.setlist(self.temp_name_param, [page])
            nex_html += f'<li><a href="?{self.query_dict.urlencode()}">{page}</a></li>'

        self.query_dict.setlist(self.temp_name_param, [self.now_page])
        now_html = f'<li class="active"><a href="?{self.query_dict.urlencode()}">{self.now_page}</a></li>'

        prev_html = ""
        if self.page_num - self.now_page <= self.prev:
            prev_list = range(self.now_page + 1, self.page_num + 1)
        else:
            prev_list = range(self.now_page + 1, self.now_page + self.prev + 1)
        for page in prev_list:
            self.query_dict.setlist(self.temp_name_param, [page])
            prev_html += f'<li><a href="?{self.query_dict.urlencode()}">{page}</a></li>'

        return nex_html + now_html + prev_html

    def show_sum_page(self):
        return f'''<li style="display: inline-block; vertical-align: middle;">
    <span class='text' style='margin-left: 10px;'>总页数：{self.page_num}</span>
</li>
'''

    def html(self):
        """ 生成全部的html
        :return: (str) html代码
        """
        html = ""
        if self.first_switch:
            html += self.page_first()
        if self.a_prev:
            html += self.page_prev()
        html += self.basic()
        if self.a_next:
            html += self.page_next()
        if self.last_switch:
            html += self.page_last()
        if self.form_switch:
            html += self.page_form()
        if self.sum_page:
            html += self.show_sum_page()

        return mark_safe(html)
